package com.victor.modular.system.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.victor.common.constant.Const;
import com.victor.common.constant.cache.CacheKey;
import com.victor.common.constant.factory.ConstantFactory;
import com.victor.common.constant.state.Status;
import com.victor.common.exception.BizExceptionEnum;
import com.victor.common.exception.ValidationException;
import com.victor.common.persistence.dao.AudienceMapper;
import com.victor.common.persistence.model.Audience;
import com.victor.config.properties.VictorProperties;
import com.victor.core.shiro.ShiroKit;
import com.victor.core.util.CommUtils;
import com.victor.core.util.ExcelUtil;
import com.victor.core.util.ToolUtil;
import com.victor.core.util.UploadFile;
import com.victor.modular.system.dao.AudienceDao;
import com.victor.modular.system.service.IAudienceService;
import com.victor.modular.system.transfer.AudienceDto;
import com.victor.modular.system.transfer.AudienceImport;
import com.victor.modular.system.transfer.FileDto;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

@Service
public class AudienceServiceImpl implements IAudienceService {
    @Autowired
    private AudienceMapper audienceMapper;
    @Autowired
    private AudienceDao audienceDao;
    /*模板*/
    @Resource
    protected VictorProperties victorProperties;
    @Override
    public void updateAudience(AudienceDto audienceDto) {
        Audience audience = new Audience();
        audience.setUpdatetime(new Date());
        audience.setUpdateUserId(ShiroKit.getUser().getId());
        BeanUtils.copyProperties(audienceDto,audience);
        audienceMapper.updateById(audience);

    }

    @Override
    public void addAudience(AudienceDto audienceDto) {
        Audience audience = new Audience();
        audience.setCreatetime(new Date());
        audience.setCreateUserId(ShiroKit.getUser().getId());
        BeanUtils.copyProperties(audienceDto,audience);
        audienceMapper.insert(audience);
    }

    @Override
    public void deleteAudience(Integer id) {
        Audience audience = audienceMapper.selectById(id);
        audienceMapper.deleteById(audience);
    }

    @Override
    public Map<String, Object> importAudience(HttpServletRequest request, FileDto fileDto) throws IOException {
        Map<String, Object> map = new HashMap<String, Object>();
        String fileName = fileDto.getFileName();
        File file = new File(victorProperties.getFileUploadTempPath() + fileName);
        map.put("success", true);
        if (file == null) {
            return CommUtils.getErrMap(BizExceptionEnum.FILE_NOT_FOUND.getMessage());
        }
        try {
            fileName = new String(fileName.getBytes("UTF-8"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return CommUtils.getErrMap(e.getMessage());
        }
        if (!fileName.toLowerCase().endsWith(".xls") && !fileName.toLowerCase().endsWith(".xlsx")) {
            return CommUtils.getErrMap("文件格式必须为 .xls或.xlsx");
        }
        UploadFile uf = new UploadFile();
        String temp = victorProperties.getFileUploadTempPath();
        String resource = victorProperties.getResourcePath();
        try {
            uf = validate(temp + fileName, resource + "audience_import.xml", uf);
        } catch (FileNotFoundException e) {
            return CommUtils.getErrMap(BizExceptionEnum.FILE_NOT_FOUND.getMessage());
        } catch (ValidationException e) {
            return CommUtils.getErrMap(BizExceptionEnum.FILE_VALID.getMessage());
        }

        if (StringUtils.isNotBlank(uf.getFailReason())) {
            map = CommUtils.getErrMap(uf.getFailReason());
            map.put("dataErr", true);
            map.put("path", victorProperties.getFileUploadTempPath());
            map.put("fail_name", uf.getFailFilePath());
            map.put("count_succ", uf.getSuccessCount() + "");
            map.put("count_fail", uf.getFailCount() + "");
            map.put("count_all", (uf.getSuccessCount() + uf.getFailCount()) + "");
            return map;
        }
        map.put("count_all", uf.getSuccessCount());
        // 校验通过
        map.put("dataList", uf.getObjList());
        request.getSession().setAttribute("AUDIENCE_IMPORT", uf.getObjList());
        return map;
    }

    @Override
    public void putAudience2Database(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute("AUDIENCE_IMPORT");
        if (obj != null) {
            List<AudienceImport> list = (List<AudienceImport>) obj;
            if (list != null && list.size() > 0) {
                int maxCount = Const.MAX_COUNT;
                int count = list.size();
                int num = count % maxCount == 0 ? count / maxCount : count / maxCount + 1;
                if (count > maxCount) {
                    for (int i = 0; i < num; i++) {
                        int begin = i * maxCount;
                        int end = (i + 1) * maxCount;
                        end = end >= count ? count : end;
                        List<AudienceImport> subList = list.subList(begin, end);
                        this.insertAudienceDatas(subList);
                    }
                } else {
                    this.insertAudienceDatas(list);
                }

            }
        }
    }
    void insertAudienceDatas(List<AudienceImport> subList){
        List<Audience> audiencelist = new ArrayList<>();
        for(AudienceImport audience:subList){
            Audience audience1= new Audience();
            BeanUtils.copyProperties(audience,audience1);
            audience1.setCreatetime(new Date());
            audience1.setCreateUserId(ShiroKit.getUser().getId());
            audiencelist.add(audience1);
        }
        audienceDao.insertAudienceDatas(audiencelist);
    }
    /*
     * Excel 校验
     */
    private UploadFile validate(String readFilePath, String resFilePath, UploadFile uf)
            throws ValidationException, IOException {
        InputStream is = null;
        ExcelUtil eu = null;
        is = new FileInputStream(readFilePath);
        eu = new ExcelUtil(is, resFilePath, AudienceImport.class);
        HashMap<Integer, String> errHash = new HashMap<>();
        List<Object> objlist = new ArrayList<>();
        HashMap<String, Integer> hash = new HashMap<>();
        while (eu.hasNext()) {
            if (eu.validate()) {
                int cur_row_number = eu.getRowIndex() - 1;
                AudienceImport audienceImport = (AudienceImport) eu.getObjectBean();
                String errmsg = "";
                // Excel本身校验
                /*if (hash.get(baseImport.getIdentifyId()) != null) {
                    errmsg = errmsg + "与第" + hash.get(baseImport.getIdentifyId()) + "行唯一ID重复;";
                } else {
                    hash.put(baseImport.getIdentifyId(), cur_row_number);
                }*/
                // 数据库校验
                // 验证产品类别*数据字典是否存在
                if (ToolUtil.isNotEmpty(audienceImport.getBusinessType1())) {
                    String name = ConstantFactory.me().getAudienceName(audienceImport.getBusinessType1());
                    if (ToolUtil.isEmpty(name)) {
                        errmsg = errmsg + "商业性质1* 数据字典不存在; ";
                    }
                }
                if (ToolUtil.isNotEmpty(audienceImport.getBusinessType2())) {
                    String name = ConstantFactory.me().getAudienceName(audienceImport.getBusinessType2());
                    if (ToolUtil.isEmpty(name)) {
                        errmsg = errmsg + "商业性质2* 数据字典不存在; ";
                    }
                }
                if (ToolUtil.isNotEmpty(audienceImport.getBusinessType3())) {
                    String name = ConstantFactory.me().getAudienceName(audienceImport.getBusinessType3());
                    if (ToolUtil.isEmpty(name)) {
                        errmsg = errmsg + "商业性质3* 数据字典不存在; ";
                    }
                }
                if (ToolUtil.isNotEmpty(audienceImport.getIndustryType())) {
                    String name = ConstantFactory.me().getAudienceName(audienceImport.getIndustryType());
                    if (ToolUtil.isEmpty(name)) {
                        errmsg = errmsg + "行业性质* 数据字典不存在; ";
                    }
                }
                if (ToolUtil.isNotEmpty(audienceImport.getProperty())) {
                    String name = ConstantFactory.me().getAudienceName(audienceImport.getProperty());
                    if (ToolUtil.isEmpty(name)) {
                        errmsg = errmsg + "客户身份* 数据字典不存在; ";
                    }
                }
                // 数据库校验
                if (errmsg.length() > 0) {
                    errHash.put(cur_row_number, errmsg);
                    uf.setFailCount(1 + uf.getFailCount());
                    uf.setFailReason(uf.getFailReason() + errmsg);
                } else {
                    uf.setSuccessCount(1 + uf.getSuccessCount());
                    objlist.add(eu.getObjectBean());
                }
            } else {
                errHash.put(eu.getRowIndex() - 1, eu.getDescription());
                uf.setFailCount(1 + uf.getFailCount());
                uf.setFailReason(uf.getFailReason() + "; " + eu.getDescription());
            }
        }
        if (errHash.size() > 0) {
            String type = readFilePath.substring(readFilePath.lastIndexOf("."));
            try {
                uf.setFailFilePath(eu.createExcelIncludeFailReason(new FileInputStream(readFilePath),
                        victorProperties.getFileUploadTempPath(), "fail" + System.nanoTime() + type, errHash));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            uf.setObjList(objlist);
        }
        return uf;
    }
}
